﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Diagnostics;

namespace MemoryLeakViewerLib
{
    public partial class MemoryLeakItem : UserControl
    {
        //protected override void OnPaint(PaintEventArgs e)
        //{
        //    base.OnPaint(e);
        //}

        public MemoryLeakItem(MemoryLeak i_MemoryLeak)
        {
            this.SuspendLayout();

            this.SetStyle(
                ControlStyles.UserPaint |
                ControlStyles.AllPaintingInWmPaint |
                ControlStyles.OptimizedDoubleBuffer, true);

            InitializeComponent();

            m_MemoryLeak = i_MemoryLeak;
            label1.Text = "Count: " + i_MemoryLeak.GetCount() + ", Size: " + i_MemoryLeak.GetSize();
            collapse();

            textBox2.Font.GetHeight();
            textBox2.Lines = i_MemoryLeak.GetDataList().ToArray();
            textBox2.Height = (textBox2.Lines.Length + 1) * textBox2.Font.Height;

            List<string> l_CallStackList = i_MemoryLeak.GetCallStackList();

            //float listBoxHeight = listBox2.Font.GetHeight() * (l_CallStackList.Count + 3);
            //listBox1.Height = Convert.ToInt32(listBoxHeight);

            //listBox2.IntegralHeight = false;
            //listBox2.Height = listBox2.PreferredHeight + 18;

            //tableLayoutPanel2.Height = tableLayoutPanel2.PreferredSize.Height;

            Regex Line = new Regex("(^.*)\\\\([^\\\\]*) \\(([0-9]*)\\): (.*)!(.*)");
            foreach (string item in l_CallStackList)
            {
                Match m = Line.Match(item);
                if (m.Success)
                {
                    //count = Convert.ToInt32(m.Groups[1].Value);

                    ListViewItem tmp = new ListViewItem(m.Groups[1].Value);  // full path
                    tmp.SubItems.Add(m.Groups[2].Value);    // filename
                    tmp.SubItems.Add(m.Groups[3].Value);    // line
                    tmp.SubItems.Add(m.Groups[5].Value);  // method
                    tmp.SubItems.Add(m.Groups[4].Value);     // dll
                    listView1.Items.Add(tmp);
                }
            }

            // TODO - There has got to be a better way to do this...
            listView1.Height = ((listView1.Items.Count) * (listView1.Font.Height+4)) + SystemInformation.HorizontalScrollBarHeight + 28;
            //listView1.Columns[0].AutoResize;// = ColumnHeaderAutoResizeStyle.ColumnContent;

            //tableLayoutPanel1.Height = tableLayoutPanel1.PreferredSize.Height;

            this.ResumeLayout();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            toggleState();
        }

        private void toggleState()
        {
            if (tableLayoutPanel3.Visible == true)
            {
                collapse();
            }
            else
            {
                expand();
            }
        }

        public void expand()
        {
            this.SuspendLayout();
            //button1.Text = "-";
            label4.Image = MemoryLeakViewerLib.Properties.Resources.Minus_WhiteBG_21;
            //panel1.Show();
            //tableLayoutPanel1.Show();
            tableLayoutPanel3.Visible = true;
            //this.Height = this.PreferredSize.Height;
            label1.BackColor = Color.Navy; //Color.DimGray;
            label1.ForeColor = Color.White;
            this.ResumeLayout();
            //Update();
        }

        public void collapse()
        {
            this.SuspendLayout();
            //button1.Text = "+";
            label4.Image = MemoryLeakViewerLib.Properties.Resources.Plus_WhiteBG_21;
            //panel1.Hide();
            //tableLayoutPanel1.Hide();
            tableLayoutPanel3.Visible = false;
            //this.Height = this.PreferredSize.Height;
            label1.BackColor = Color.Gainsboro;
            label1.ForeColor = Color.Black;
            this.ResumeLayout();
            //Update();
        }

        public MemoryLeak getMemoryLeak()
        {
            return m_MemoryLeak;
        }

        private Color m_MyColor = Color.FromArgb(0xFF, 0xFF, 0xFF);
        private MemoryLeak m_MemoryLeak;

        private void label1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            //toggleState();
        }

        private void label1_Click(object sender, EventArgs e)
        {
            toggleState();
        }

        private void label4_Click(object sender, EventArgs e)
        {
            toggleState();
        }

        void OpenSelectedItemInVisualStudio()
        {
            string path = listView1.SelectedItems[0].SubItems[0].Text;
            string filename = listView1.SelectedItems[0].SubItems[1].Text;
            string line = listView1.SelectedItems[0].SubItems[2].Text;
            int nLine = Convert.ToInt32(line);

            string fullPath = path + "\\" + filename;

            if (Program.m_ApplicationObject != null)
            {
                try
                {
                    Program.m_ApplicationObject.SuppressUI = true;
                    Program.m_ApplicationObject.ItemOperations.OpenFile(fullPath);
                    EnvDTE.TextSelection temp = Program.m_ApplicationObject.ActiveDocument.Selection;
                    temp.GotoLine(nLine, true);
                    //temp
                }
                catch
                {

                }
            }
            else
            {
                //string Command = "CMD.exe /C \"C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Common7\\IDE\\devenv.exe\" \"C:\\CyberHawkProjects\\Branches\\Redesign\\Code\\CyberSolution\\ConnectionCommon\\AtPhone.cpp\" /command \"edit.goto 303\"";
                string Command = "C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Common7\\IDE\\devenv.exe";
                //string Command = "notepad.exe";
                string Arguments = /*"/edit " +*/ "\"" + fullPath + "\" /command \"edit.goto " + line + "\"";

                //Declare and instantiate a new process component.
                System.Diagnostics.Process process1;
                process1 = new System.Diagnostics.Process();

                //Do not receive an event when the process exits.
                process1.EnableRaisingEvents = false;


                //The "/C" Tells Windows to Run The Command then Terminate 
                //string strCmdLine;
                //strCmdLine = "/C regenresx " + textBox1.Text + " " + textBox2.Text;
                //System.Diagnostics.Process.Start("CMD.exe", strCmdLine);
                System.Diagnostics.Process.Start(Command, Arguments);
                process1.Close();
            }
        }

        private void listView1_DoubleClick(object sender, EventArgs e)
        {
            OpenSelectedItemInVisualStudio();
        }

        private void openInVisualStudioToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenSelectedItemInVisualStudio();
        }

        private void listView1_Leave(object sender, EventArgs e)
        {
            listView1.SelectedItems.Clear();
        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            ProcessSelectedItem();
        }

        void ProcessSelectedItem()
        {
            if (listView1.SelectedItems.Count > 0)
            {
                string path = listView1.SelectedItems[0].SubItems[0].Text;
                string filename = listView1.SelectedItems[0].SubItems[1].Text;
                string line = listView1.SelectedItems[0].SubItems[2].Text;
                int nLine = Convert.ToInt32(line);

                string fullPath = path + "\\" + filename;

                //if (Program.m_ApplicationObject != null)
                //{
                //    try
                //    {
                //        Program.m_ApplicationObject.SuppressUI = true;
                //        Program.m_ApplicationObject.ItemOperations.OpenFile(fullPath);
                //        EnvDTE.TextSelection temp = Program.m_ApplicationObject.ActiveDocument.Selection;
                //        temp.GotoLine(nLine, true);
                //    }
                //    catch
                //    { 

                //    }
                //}

                if (Program.m_codeView != null)
                {
                    Program.m_codeView.Show();
                    Program.m_codeView.SetText(fullPath, nLine);
                }
            }
        }

        private void listView1_MouseClick(object sender, MouseEventArgs e)
        {
            // Right Click Menu
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                if (listView1.SelectedItems.Count > 0)
                {
                    contextMenuStrip1.Show(listView1, new Point(e.X, e.Y));
                }
            }
        }

        private void listView1_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.Handled = true;
                e.SuppressKeyPress = true;
                OpenSelectedItemInVisualStudio();
            }
        }
    }
}
